package com.ncepu.thumb.job;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrPool;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ncepu.thumb.mapper.BlogMapper;
import com.ncepu.thumb.model.entity.Thumb;
import com.ncepu.thumb.model.enums.ThumbTypeEnum;
import com.ncepu.thumb.service.ThumbService;
import com.ncepu.thumb.utils.RedisKeyUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author simon_jiang
 * @version 1.0
 */
@Component
@Slf4j
public class SyncThumb2DBJob {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private ThumbService thumbService;
    @Resource
    private BlogMapper blogMapper;

    @Scheduled(fixedRateString = "${thumb.sync.fixedRate}")
    @Transactional(rollbackFor = Exception.class)
    public void run() {
//        log.info("定时任务开始执行");
        DateTime nowDate = DateUtil.date();
        int second = (nowDate.second() / 10 - 1) * 10;
        if(second == -10) {
            second = 50;
            nowDate = DateUtil.offsetMinute(nowDate, -1);
        }
        String date = DateUtil.format(nowDate, "HH:mm:") + second;
        syncThumb2DBByDate(date);
//        log.info("定时任务执行结束");
    }

    public void syncThumb2DBByDate(String date) {
        String tempThumbKey = RedisKeyUtil.getTempThumbKey(date);
        Map<Object, Object> allTempThumbMap = redisTemplate.opsForHash().entries(tempThumbKey);
        boolean isEmpty = CollUtil.isEmpty(allTempThumbMap);
        if(isEmpty) {
            return;
        }

        // 构建一个博客点赞数量map,用于批量插入
        Map<Long, Long> blogThumbCountMap = new HashMap<>();
        // 构建一个List,表示要插入到Thumb表中的数据
        ArrayList<Thumb> thumbList = new ArrayList<>();
        boolean needRemove = false;
        LambdaQueryWrapper<Thumb> wrapper = new LambdaQueryWrapper<>();
        for(Object userIdBlogIdObj : allTempThumbMap.keySet()) {
            String userIdBlogId = (String) userIdBlogIdObj;
            String[] userIdAndBlogId = userIdBlogId.split(StrPool.COLON);
            Long userId = Long.valueOf(userIdAndBlogId[0]);
            Long blogId = Long.valueOf(userIdAndBlogId[1]);
            // 获取是取消点赞还是点赞
            long thumbType = Long.parseLong(allTempThumbMap.get(userIdBlogIdObj).toString());
            if(thumbType == ThumbTypeEnum.INCR.getValue()) {
                Thumb thumb = new Thumb();
                thumb.setUserId(userId);
                thumb.setBlogId(blogId);
                thumbList.add(thumb);
            }else if (thumbType == ThumbTypeEnum.DECR.getValue()) {
                needRemove = true;
                wrapper.or()
                        .eq(Thumb::getUserId, userId)
                        .eq(Thumb::getBlogId, blogId);
            }else {
                if(thumbType != ThumbTypeEnum.NON.getValue()) {
                    log.warn("数据异常：｛｝", userId + "," + blogId + "," + thumbType);
                }
                continue;
            }
            blogThumbCountMap.merge(blogId, thumbType, Long::sum);
        }
        // 批量插入
        thumbService.saveBatch(thumbList);
        // 批量删除
        if(needRemove) {
            thumbService.remove(wrapper);
        }

        // 更新博客点赞数量
        if(!blogThumbCountMap.isEmpty()) {
            blogMapper.batchUpdateThumbCount(blogThumbCountMap);
        }

        // 异步删除临时数据
//        new Thread(() -> redisTemplate.delete(tempThumbKey)).start();
        Thread.startVirtualThread(() -> redisTemplate.delete(tempThumbKey));
    }

}
